package com.zhentao.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.RandomUtil;
import com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;
import com.zhentao.dto.FaceLoginRequest;
import com.zhentao.dto.FaceRegisterRequest;
import com.zhentao.mapper.SysUserMapper;
import com.zhentao.pojo.SysUser;
import com.zhentao.service.FaceAuthService;
import com.zhentao.service.FaceEngineService;
import com.zhentao.service.SysUserService;
import com.zhentao.util.Result;
import com.zhentao.util.SaltMD5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 人脸认证服务实现
 */
@Service
public class FaceAuthServiceImpl implements FaceAuthService {
    
    private static final Logger logger = LoggerFactory.getLogger(FaceAuthServiceImpl.class);
    
    @Autowired
    private FaceEngineService faceEngineService;
    
    @Autowired
    private SysUserService sysUserService;
    
    @Autowired
    private SysUserMapper sysUserMapper;
    
    @Override
    public Result faceRegister(FaceRegisterRequest request) {
        try {
            // 参数校验
            if (StringUtils.isEmpty(request.getName()) || StringUtils.isEmpty(request.getRealName()) 
                || StringUtils.isEmpty(request.getPassword()) || StringUtils.isEmpty(request.getFaceImage())) {
                return Result.ERROR("用户名、真实姓名、密码和人脸图片都不能为空！");
            }
            
            // 检查用户名是否已存在
            SysUser existUser = sysUserService.query()
                    .eq("name", request.getName())
                    .one();
            if (existUser != null) {
                return Result.ERROR("用户名已存在！");
            }
            
            // 提取人脸特征
            byte[] faceFeature = extractFaceFeature(request.getFaceImage());
            if (faceFeature == null) {
                return Result.ERROR("未检测到人脸或人脸特征提取失败！");
            }
            
            // 创建用户对象
            SysUser user = new SysUser();
            user.setName(request.getName());
            user.setRealName(request.getRealName());
            user.setPassword(SaltMD5Util.generateSaltPassword(request.getPassword()));
            user.setPhoneNumber(request.getPhoneNumber());
            user.setEmail(request.getEmail());
            user.setFaceFeature(faceFeature);
            user.setFaceId(RandomUtil.randomString(10));
            user.setGroupId(request.getGroupId());
            user.setStatus(1); // 默认启用
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            
            // 保存用户
            if (sysUserService.save(user)) {
                logger.info("用户人脸注册成功: {}", request.getName());
                return Result.OK("注册成功");
            } else {
                return Result.ERROR("用户注册失败");
            }
            
        } catch (Exception e) {
            logger.error("人脸注册异常", e);
            return Result.ERROR("注册过程中发生异常");
        }
    }
    
    @Override
    public Result faceLogin(FaceLoginRequest request) {
        try {
            // 参数校验
            if (StringUtils.isEmpty(request.getFaceImage())) {
                return Result.ERROR("人脸图片不能为空！");
            }
            
            // 提取人脸特征
            byte[] faceFeature = extractFaceFeature(request.getFaceImage());
            if (faceFeature == null) {
                return Result.ERROR("未检测到人脸或人脸特征提取失败！");
            }
            
            // 人脸比对
            SysUser matchedUser = compareFaceFeature(faceFeature, request.getGroupId());
            if (matchedUser != null) {
                // 检查账号状态
                if (matchedUser.getStatus() == 0) {
                    return Result.ERROR("账号已被禁用，请联系管理员！");
                }
                
                logger.info("用户人脸登录成功: {}", matchedUser.getName());
                return Result.OK(matchedUser);
            } else {
                return Result.ERROR("人脸识别失败，未找到匹配用户！");
            }
            
        } catch (Exception e) {
            logger.error("人脸登录异常", e);
            return Result.ERROR("登录过程中发生异常");
        }
    }
    
    @Override
    public byte[] extractFaceFeature(String faceImageBase64) {
        try {
            // 处理Base64字符串
            String processedBase64 = base64Process(faceImageBase64);
            
            // 解析图片
            byte[] decode = Base64.decode(processedBase64);
            ImageInfo imageInfo = ImageFactory.getRGBData(decode);
            
            // 提取人脸特征
            return faceEngineService.extractFaceFeature(imageInfo);
            
        } catch (Exception e) {
            logger.error("人脸特征提取异常", e);
            return null;
        }
    }
    
    @Override
    public SysUser compareFaceFeature(byte[] faceFeature, Integer groupId) {
        try {
            logger.info("开始人脸比对，groupId: {}, 人脸特征长度: {}", groupId, faceFeature != null ? faceFeature.length : 0);
            
            // 使用人脸引擎进行比对，设置90%相似度阈值
            List<com.zhentao.dto.FaceUserInfo> matchedUsers = faceEngineService.compareFaceFeature(faceFeature, groupId);
            
            logger.info("人脸引擎比对完成，返回匹配用户数量: {}", matchedUsers != null ? matchedUsers.size() : 0);
            
            if (CollectionUtil.isNotEmpty(matchedUsers)) {
                // 打印所有匹配用户的相似度
                for (com.zhentao.dto.FaceUserInfo user : matchedUsers) {
                    logger.info("匹配用户: {}, faceId: {}, 相似度: {}%", 
                        user.getName(), user.getFaceId(), user.getSimilarValue());
                }
                
                // 筛选相似度达到90%以上的用户
                List<com.zhentao.dto.FaceUserInfo> qualifiedUsers = new ArrayList<>();
                for (com.zhentao.dto.FaceUserInfo user : matchedUsers) {
                    if (user.getSimilarValue() != null && user.getSimilarValue() >= 90) {
                        qualifiedUsers.add(user);
                        logger.info("用户 {} 通过90%相似度验证，相似度: {}%", user.getName(), user.getSimilarValue());
                    }
                }
                
                logger.info("通过90%相似度阈值的用户数量: {}", qualifiedUsers.size());
                
                if (CollectionUtil.isNotEmpty(qualifiedUsers)) {
                    // 获取相似度最高的用户
                    com.zhentao.dto.FaceUserInfo bestMatch = qualifiedUsers.get(0);
                    
                    logger.info("人脸比对成功，用户: {}, 相似度: {}%", bestMatch.getName(), bestMatch.getSimilarValue());
                    
                    // 根据faceId查找对应的SysUser
                    SysUser user = sysUserService.query()
                            .eq("face_id", bestMatch.getFaceId())
                            .eq("status", 1)
                            .one();
                    
                    if (user != null) {
                        logger.info("找到对应的SysUser: {}, ID: {}", user.getName(), user.getId());
                    } else {
                        logger.warn("未找到对应的SysUser，faceId: {}", bestMatch.getFaceId());
                    }
                    
                    return user;
                } else {
                    logger.info("人脸比对失败，相似度未达到90%阈值，最高相似度: {}%", 
                        matchedUsers.isEmpty() ? 0 : matchedUsers.get(0).getSimilarValue());
                }
            } else {
                logger.info("人脸比对失败，未找到匹配的用户");
            }
            
        } catch (Exception e) {
            logger.error("人脸比对异常", e);
        }
        
        logger.info("人脸比对结束，返回null");
        return null;
    }
    
    /**
     * 处理Base64字符串，去除前缀
     */
    private String base64Process(String base64Str) {
        if (!StringUtils.isEmpty(base64Str)) {
            String photoBase64 = base64Str.substring(0, Math.min(30, base64Str.length())).toLowerCase();
            int indexOf = photoBase64.indexOf("base64,");
            if (indexOf > 0) {
                base64Str = base64Str.substring(indexOf + 7);
            }
            return base64Str;
        } else {
            return "";
        }
    }
}
